-module(army).

-include("records.hrl").
-include_lib("eunit/include/eunit.hrl").
-include_lib("stdlib/include/qlc.hrl").

find_all() -> 
	Query = qlc:q([B || B <- mnesia:table(army)]),
	{atomic, Armies} = active_record:find(Query),
	Armies.

new(Troops) -> #army{troops = Troops}.
	
create(Troops) -> 
	Army = new(Troops),
	active_record:create(Army#army{id = rand:new()}).

merge(Army, [Troop | Others]) -> 
	merge(Army, Troop),
	merge(Army, Others);
merge(Army, Troop) -> 
	% TODO: not yet implemented
	Army.

get_attack(Army) -> lists:foldl(fun(Troop, Sum) -> troop:get_attack(Troop) + Sum end, 0, Army#army.troops).

get_defense(Army) -> lists:foldl(fun(Troop, Sum) -> troop:get_defense(Troop) + Sum end, 0, Army#army.troops).

%% Tests

creation_test_() ->
	Branch1 = branch:new("Infantry", 4, 3),
	Troop1 = troop:new(Branch1, 10),
	Branch2 = branch:new("Armor", 5, 8),
	Troop2 = troop:new(Branch2, 5),
	Army = new([Troop1, Troop2]),
	[
	?_assertMatch(65, get_attack(Army)),
	?_assertMatch(70, get_defense(Army))
	].
	
find_all_test_() ->
	[Army1, Army2, ArmiesBeforeCreate, ArmiesAfterCreate, ArmiesAfterCreate2] = active_record:in_test_db(
		fun() -> 
			ArmiesBeforeCreate = find_all(),
			Branch1 = branch:new("Infantry", 4, 3),
			Troop1 = troop:new(Branch1, 10),
			Army1 = create([Troop1]),
			ArmiesAfterCreate = find_all(),
			Branch2 = branch:new("Armor", 5, 8),
			Troop2 = troop:new(Branch2, 5),
			Army2 = create([Troop2]),
			ArmiesAfterCreate2 = find_all(),
			[Army1, Army2, ArmiesBeforeCreate, ArmiesAfterCreate, ArmiesAfterCreate2]
		end
	),
	[
	?_assertMatch([], ArmiesBeforeCreate),
	?_assertMatch([Army1], ArmiesAfterCreate),
	?_assertMatch(false, lists:member(Army2, ArmiesAfterCreate)),
	?_assertMatch(true, lists:member(Army1, ArmiesAfterCreate2)),
	?_assertMatch(true, lists:member(Army2, ArmiesAfterCreate2))
	].
	
merge_test_() ->
	Army = active_record:in_test_db(
		fun() ->
			Tank = branch:new("Tank", 12, 15),
			TankTroop = troop:new(Tank, 3),
			Helicopter = branch:new("Helicopter", 11, 6),
			HelicopterTroop = troop:new(Helicopter, 1),
			Army = create([TankTroop, HelicopterTroop]),
			AnotherTankTroop = troop:new(Tank, 2),
			Infantry = branch:new("Infantry", 4, 3),
			InfantryTroop = troop:new(Infantry, 10),
			merge(Army, [AnotherTankTroop, InfantryTroop]),
			Army
		end
	),
	[
	% TODO： not implemented yet
	% ?_assertMatch([_, _, _], Army#army.troops),
	?_assertMatch(1, 1)
	].